/*
 * Edge CLASS TEMPLATE:
 *  Represents concept of plain edge comprising 2 plain vertices.
 *
 * WeightedEdge CLASS TEMPLATE:
 *  Represents concept of weighted edge based on plain edge.
 *
 */

#ifndef UNITRAF_GRAPHTRAITS_EDGE_HPP
#define UNITRAF_GRAPHTRAITS_EDGE_HPP

#include <graph\traits\Vertex.hpp>
#include <graph\IteratorAdaptor.hpp>


namespace unitraf {

namespace graph_traits {

/////////////////////////////////////////////////////////////////////////////
// EDGE DETAILS

template<class _Property> class Edge;

template<> class Edge<no_property_tag> {

  typedef Edge _myt;

  // Comparator, to introduce strict weak ordering upon set of edges
  friend bool operator<(const _myt& lh, const _myt& rh) {
    if (lh.source_ < rh.source_)
      return 1;
    else
      if (lh.source_ == rh.source_) return (lh.target_ < rh.target_);
      else return 0;
  };

 public:
  /////////////////////////////////////////////////////////////////////////////
  // PUBLIC INTERFACE

  typedef Vertex<no_property_tag> vertex_descriptor;

  // CONSTRUCTORS AND INITIALIZERS

  Edge(const vertex_descriptor& source, const vertex_descriptor& target) : source_(source), target_(target) {};
        

  // ACCESSORS

  vertex_descriptor source() const { return source_; };
    
  vertex_descriptor target() const { return target_; };

 private:
  /////////////////////////////////////////////////////////////////////////////
  // REPRESENTATION

  vertex_descriptor source_;

  vertex_descriptor target_;
  
};

template<class _Property> class Edge : public Edge<no_property_tag> {

  typedef Edge<no_property_tag> _base;

 public:
  /////////////////////////////////////////////////////////////////////////////
  // PUBLIC INTERFACE

  typedef _Property property_type;

  Edge(const _base& base) 
    : _base(base) {};
  
  Edge(const vertex_descriptor& source, const vertex_descriptor& target) 
    : _base(source, target) {};

  Edge(const vertex_descriptor& source, const vertex_descriptor& target, 
    const property_type& prop) : _base(source, target), property_proxy(prop) {};

  ~Edge() {};

  // REPRESENTATION

  mutable property_type property_proxy;

};

};  // namespace graph_traits

};  // namespace unitraf

#endif  // #ifndef UNITRAF_GRAPHTRAITS_EDGE_HPP
